package com.eshop.tools.service.impl;

import java.lang.invoke.SerializedLambda;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eshop.utils.ValidationUtil;
import java.io.Serializable;
import cn.hutool.json.JSONObject;
import java.io.File;
import com.alibaba.fastjson.JSON;
import com.eshop.exception.BadRequestException;
import com.eshop.utils.TranslatorUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.http.HttpRequest;
import java.util.HashMap;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Iterator;
import com.eshop.utils.FileUtil;
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.eshop.common.utils.QueryHelpPlus;
import com.eshop.tools.service.dto.PictureDto;
import java.util.LinkedHashMap;
import java.util.List;
import com.github.pagehelper.PageInfo;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import com.eshop.tools.service.dto.PictureQueryCriteria;
import org.springframework.beans.factory.annotation.Value;
import com.eshop.dozer.service.IGenerator;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import com.eshop.tools.service.PictureService;
import com.eshop.tools.domain.Picture;
import com.eshop.tools.service.mapper.PictureMapper;
import com.eshop.common.service.impl.BaseServiceImpl;

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = { Exception.class })
public class PictureServiceImpl extends BaseServiceImpl<PictureMapper, Picture> implements PictureService
{
    private final IGenerator generator;
    @Value("${smms.token}")
    private String token;
    private static final String SUCCESS = "success";
    private static final String CODE = "code";
    private static final String MSG = "message";
    
    public PictureServiceImpl(final IGenerator generator) {
        this.generator = generator;
    }
    
    public Map<String, Object> queryAll(final PictureQueryCriteria criteria, final Pageable pageable) {
        this.getPage(pageable);
        final PageInfo<Picture> page = (PageInfo<Picture>)new PageInfo((List)this.queryAll(criteria));
        final Map<String, Object> map = new LinkedHashMap<String, Object>(2);
        map.put("content", this.generator.convert(page.getList(), (Class)PictureDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }
    
    public List<Picture> queryAll(final PictureQueryCriteria criteria) {
        return (List<Picture>)((PictureMapper)this.baseMapper).selectList((Wrapper)QueryHelpPlus.getPredicate(Picture.class, criteria));
    }
    
    public void download(final List<PictureDto> all, final HttpServletResponse response) throws IOException {
        final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (final PictureDto picture : all) {
            final Map<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("上传日期", picture.getCreateTime());
            map.put("删除的URL", picture.getDeleteUrl());
            map.put("图片名称", picture.getFilename());
            map.put("图片高度", picture.getHeight());
            map.put("图片大小", picture.getSize());
            map.put("图片地址", picture.getUrl());
            map.put("用户名称", picture.getUsername());
            map.put("图片宽度", picture.getWidth());
            map.put("文件的MD5值", picture.getMd5code());
            list.add(map);
        }
        FileUtil.downloadExcel((List)list, response);
    }
    
    @Transactional(rollbackFor = { Throwable.class })
    public Picture upload(final MultipartFile multipartFile, final String username) {
        final File file = FileUtil.toFile(multipartFile);
        Picture picture = (Picture)this.getOne((Wrapper) Wrappers.<Picture>lambdaQuery().eq(Picture::getMd5code, FileUtil.getMd5(file)));
        if (picture != null) {
            return picture;
        }
        final HashMap<String, Object> paramMap = new HashMap<String, Object>(1);
        paramMap.put("smfile", file);
        final String result = ((HttpRequest)HttpRequest.post("https://sm.ms/api/v2/upload").header("Authorization", this.token)).form((Map)paramMap).timeout(20000).execute().body();
        final JSONObject jsonObject = JSONUtil.parseObj(result);
        if (!jsonObject.get("code").toString().equals("success")) {
            throw new BadRequestException(TranslatorUtil.translate(jsonObject.get("message").toString()));
        }
        picture = (Picture)JSON.parseObject(jsonObject.get("data").toString(), (Class)Picture.class);
        picture.setSize(FileUtil.getSize((long)Integer.parseInt(picture.getSize())));
        picture.setUsername(username);
        picture.setMd5code(FileUtil.getMd5(file));
        picture.setFilename(FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) + "." + FileUtil.getExtensionName(multipartFile.getOriginalFilename()));
        this.save(picture);
        FileUtil.del(file);
        return picture;
    }
    
    public Picture findById(final Long id) {
        final Picture picture = (Picture)this.getById((Serializable)id);
        ValidationUtil.isNull(picture.getId(), "Picture", "id", id);
        return picture;
    }
    
    public void deleteAll(final Long[] ids) {
        for (final Long id : ids) {
            final Picture picture = this.findById(id);
            try {
                HttpUtil.get(picture.getDeleteUrl());
                this.removeById((Serializable)id);
            }
            catch (Exception e) {
                this.removeById((Serializable)id);
            }
        }
    }
    
    public void synchronize() {
        final String result = ((HttpRequest)HttpRequest.get("https://sm.ms/api/v2/upload_history").header("Authorization", this.token)).timeout(20000).execute().body();
        final JSONObject jsonObject = JSONUtil.parseObj(result);
        final List<Picture> pictures = (List<Picture>)JSON.parseArray(jsonObject.get("data").toString(), (Class)Picture.class);
        for (final Picture picture : pictures) {
            if (this.getOne((Wrapper)Wrappers.<Picture>lambdaQuery().eq(Picture::getUrl, picture.getUrl())) == null) {
                picture.setSize(FileUtil.getSize((long)Integer.parseInt(picture.getSize())));
                picture.setUsername("System Sync");
                picture.setMd5code(null);
                this.save(picture);
            }
        }
    }
}
